﻿using SIG.Basic.Extensions;
using SIG.Data.Repositories.Case;
using SIG.Infrastructure.Cache;
using SIG.Infrastructure.Configs;
using SIG.Infrastructure.Logging;
using SIG.Model.Case;
using SIG.Resources.Admin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace SIG.Service.Case
{
    public class ClientService : EntityService<Client>, IClientService
    {

        private readonly IClientRepository _clientRepository;
        private readonly ILoggingService _loggingService;
        private readonly ICacheService _cacheService;

        public ClientService(IClientRepository clientRepository, ILoggingService loggingService, ICacheService cacheService)
            : base(clientRepository, cacheService, loggingService)
        {
            _clientRepository = clientRepository;
            _loggingService = loggingService;
            _cacheService = cacheService;
        }

        public Client GetByIdWithWorks(int id)
        {

            var key = $"{EntityNames.Client}_ById_{id}";
            if (!SettingsManager.Client.EnableCaching)
            {
                return _clientRepository.GetFirstOrDefault(p => p.Id == id,p=>p.Works);
            }

            if (_cacheService.IsSet(key))
            {
                return (Client)_cacheService.Get(key);

            }

            var client = _clientRepository.GetFirstOrDefault(p => p.Id == id, p => p.Works);
            _cacheService.Set(key, client, SettingsManager.Client.CacheDuration);


            return client;
        }

        public List<Client> GetPagedElements(int pageIndex, int pageSize, string keyword, out int totalCount)
        {

            //get list count
            var keyCount = $"{EntityNames.Client}_ListCount_{keyword}";

            var totalIQuery = _clientRepository.GetAllElements();
            if (!string.IsNullOrEmpty(keyword))
                totalIQuery = totalIQuery.Where(g => g.ClientName.Contains(keyword));

            if (SettingsManager.Client.EnableCaching)
            {
                if (_cacheService.IsSet(keyCount))
                {
                    totalCount = (int)_cacheService.Get(keyCount);
                }
                else
                {
                    totalCount = totalIQuery.Count();
                    _cacheService.Set(keyCount, totalCount, SettingsManager.Client.CacheDuration);
                }
            }
            else
            {
                totalCount = totalIQuery.Count();
            }


            //get list
            var key = $"{EntityNames.Client}_List_{pageIndex}_{pageSize}_{keyword}";

            List<Client> clients;
            Expression<Func<Client, bool>> filter = g => true;
            Expression<Func<Client, bool>> filterByKeyword = g => g.ClientName.Contains(keyword);


            if (!string.IsNullOrEmpty(keyword))
                filter = filter.AndAlso(filterByKeyword);


            if (SettingsManager.Client.EnableCaching)
            {
                if (_cacheService.IsSet(key))
                {
                    clients = (List<Client>)_cacheService.Get(key);

                }
                else
                {
                    clients = _clientRepository.GetPagedElements(pageIndex, pageSize, (c => c.Importance), filter, false).ToList();
                    _cacheService.Set(key, clients, SettingsManager.Client.CacheDuration);
                }
            }
            else
            {
                clients = _clientRepository.GetPagedElements(pageIndex, pageSize, (c => c.Importance), filter, false).ToList();
            }

            return clients;

        }

        public IEnumerable<Client> LatesterClients(int count)
        {
            var key = $"{EntityNames.Client}s_Latester_{count}";

            if (!SettingsManager.Client.EnableCaching)
            {
                return _clientRepository.GetPagedElements(0, count, p => p.Importance, p => p.Active, false).ToList();
            }

            if (_cacheService.IsSet(key))
            {
                return (List<Client>)_cacheService.Get(key);

            }

            var announcementList = _clientRepository.GetPagedElements(0, count, p => p.Importance, p => p.Active, false).ToList();
            _cacheService.Set(key, announcementList, SettingsManager.Client.CacheDuration);


            return announcementList;
        }

    }
}
